﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Vision.Common
{
    //绘制图元
    public class CDrawRect : CDrawObj
    {
        public const byte DirAll = 0x0F;
        public const byte DirLeft = 0x01;
        public const byte DirTop = 0x02;
        public const byte DirRight = 0x04;
        public const byte DirBottom = 0x08;
        public const int subWidth = 25;

        static protected Pen BorderPen { get; set; } = new Pen(Color.Red, 2);//边框颜色
        static protected Pen BorderPenSelected { get; set; }= new Pen(Color.Green, 2);//边框颜色
        static protected SolidBrush FillBrush { get; set; }= new SolidBrush(Color.FromArgb(30, 255, 0, 0));
        static protected SolidBrush FillBrushSelected { get; set; }= new SolidBrush(Color.FromArgb(30, 0, 255, 0));
        static protected SolidBrush BorderBrush { get; set; }= new SolidBrush(Color.Yellow);
        
        protected PointF startPoint = new Point(0, 0);    //屏幕起点
        /// <summary>
        /// 起始点，X屏幕水平向右，Y屏幕竖直向下
        /// </summary>
        public PointF StartPoint
        {
            get => startPoint;
            set => startPoint = value;
        }

        protected SizeF size = new Size(0, 0);     //屏幕尺寸
        public SizeF Size
        {
            get => size;
            set => size = value;
        }

        public Rectangle Rect
        {
            get=> new Rectangle((int) StartPoint.X, (int) StartPoint.Y,
                         (int) Size.Width, (int) Size.Height);
        }
        public float angle = 0;                        //角度
        /// <summary>
        /// 角度，顺时针
        /// </summary>
        public float Angle
        {
            get => angle;
            set => angle = value;
        }
        //static CDrawRect()
        //{
        //    BorderPen = new Pen(Color.Red,2);
        //    BorderPenSelected = new Pen(Color.Green,2);
        //    FillBrush = new SolidBrush(Color.FromArgb(60, 255, 0, 0));
        //    FillBrushSelected = new SolidBrush(Color.FromArgb(60, 0, 255, 0));
        //    BorderBrush = new SolidBrush(Color.Yellow);
        //}
        public CDrawRect()
        {
        }
        
        
        //调整大小
        //public void ReSize(Point endPt,lineStyle style)
        //{
        //    //PointF ptCenter = new PointF(m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2);
        //    Matrix matrix = new Matrix();
        //    matrix.Rotate(-m_angle);
        //    matrix.Translate(endPt.X - m_center.X, endPt.Y - m_center.Y);
        //    switch(style)
        //    {
        //        case lineStyle.ox://X方向
        //            m_start.X = (int)(m_center.X - Math.Abs(matrix.OffsetX));
        //            m_size.Width = (m_center.X-m_start.X)*2;
        //            break;
        //        case lineStyle.oy://y方向
        //            m_start.Y = (int)(m_center.Y - Math.Abs(matrix.OffsetY));
        //            m_size.Height = (m_center.Y - m_start.Y) * 2;
        //            break;
        //        case lineStyle.xy://xy方向
        //            m_start.X = (int)(m_center.X - Math.Abs(matrix.OffsetX));
        //            m_size.Width = (m_center.X - m_start.X) * 2;
        //            m_start.Y = (int)(m_center.Y - Math.Abs(matrix.OffsetY));
        //            m_size.Height = (m_center.Y - m_start.Y) * 2;
        //            break;
        //        default:
        //            break;
        //    }
        //}

        //判断顺序，1.先判断是否为边，再判断是否在中心；2.判断边，右下大于左上
        //角点 2像素
        byte curDir = 0;
        public TrackerPos GetDirect(PointF pt,out byte curDir)
        {
            Matrix matrix = new Matrix();
            matrix.Rotate(-angle);
            matrix.Translate(pt.X - startPoint.X, pt.Y - startPoint.Y);//求宽高
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, -subWidth, size.Width + subWidth, -subWidth, size.Height + subWidth) == false)
            {
                curDir = 0;
                return TrackerPos.tOut;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, size.Width - subWidth, size.Width + subWidth, size.Height - subWidth, size.Height + subWidth))
            {
                Console.WriteLine(5);
                curDir = DirRight | DirBottom;
                return TrackerPos.tBorderTwo;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, size.Width - subWidth, size.Width + subWidth, size.Height / 2 - subWidth, size.Height / 2 + subWidth))
            {
                Console.WriteLine(4);
                curDir = DirRight;
                return TrackerPos.tBorderOne;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, size.Width / 2 - subWidth, size.Width / 2 + subWidth, size.Height - subWidth, size.Height + subWidth))
            {
                Console.WriteLine(6);
                curDir = DirBottom;
                return TrackerPos.tBorderOne;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, -subWidth, +subWidth, size.Height / 2 - subWidth, size.Height / 2 + subWidth))
            {
                Console.WriteLine(8);
                curDir = DirLeft;
                return TrackerPos.tBorderOne;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, size.Width / 2 - subWidth, size.Width / 2 + subWidth, -subWidth, +subWidth))
            {
                Console.WriteLine(2);
                curDir = DirTop;
                return TrackerPos.tBorderOne;
            }

            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, -subWidth, +subWidth, size.Height - subWidth, size.Height + subWidth))
            {
                Console.WriteLine(7);
                curDir = DirLeft | DirBottom;
                return TrackerPos.tBorderTwo;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, size.Width - subWidth, size.Width + subWidth, -subWidth, +subWidth))
            {
                Console.WriteLine(3);
                curDir = DirTop | DirRight;
                return TrackerPos.tBorderTwo;
            }
            if (IntersectsWith(matrix.OffsetX, matrix.OffsetY, -subWidth, +subWidth, -subWidth, +subWidth))
            {
                Console.WriteLine(1);
                curDir = DirLeft | DirTop;
                return TrackerPos.tBorderTwo;
            }
            Console.WriteLine(-1);
            curDir = 0;
            return TrackerPos.tIn;
        }

        public override TrackerInfo GetTrack(PointF pt, float scale)
        {
            var res = new TrackerInfo();
            byte info;
            res.pos = GetDirect(pt,out info);
            res.para = info;
            return res;
        }

        /// <summary>
        /// 调整大小
        /// </summary>
        /// <param name="endPt"></param>
        /// <param name="type"></param>
        public void ReSize(PointF endPt, int type = DirRight | DirBottom)
        {
            //PointF ptCenter = new PointF(m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2);
            Matrix matrix = new Matrix();
            matrix.Rotate(-angle);
            matrix.Translate(endPt.X - startPoint.X, endPt.Y - startPoint.Y);//求宽高
            float nx = 0;
            float ny = 0;
            if ((type & DirRight) > 0)
            {
                size.Width = Math.Max(1, matrix.OffsetX);
            }
            else if ((type & DirLeft) > 0)
            {
                nx = Math.Min(size.Width - 1, matrix.OffsetX);//距离最右点距离
            }
            if ((type & DirBottom) > 0)
            {
                size.Height = Math.Max(1, matrix.OffsetY);
            }
            else if ((type & DirTop) > 0)
            {
                ny = Math.Min(size.Height - 1, matrix.OffsetY);//距离最右点距离
            }
            if (nx != 0 || ny != 0)
            {
                matrix.Reset();
                matrix.Translate(startPoint.X, startPoint.Y);
                matrix.Rotate(angle);
                matrix.Translate(nx, ny);
                startPoint.X = matrix.OffsetX;
                startPoint.Y = matrix.OffsetY;
                size.Width -= nx;
                size.Height -= ny;
            }
        }

        public override void Move(float dx,float dy)
        {
            startPoint.X += dx;
            startPoint.Y += dy;
        }

        //绘制
        public override void Draw(Graphics g, float scale = 1)
        {
            if (m_visible == false)
                return;
            int startX = 0;
            int startY = 0;
            Rectangle rectangle = new Rectangle(startX, startY, (int)size.Width, (int)size.Height);
            if (scale > 1)
                scale = 1;
            Pen curPen = State == TrackerState.normal ? BorderPen: BorderPenSelected;
            SolidBrush solidBrush = State == TrackerState.normal ? FillBrush: FillBrushSelected;
            float crossWidth = Math.Min(size.Width / 2, 5 / scale);
            float crossHeight = Math.Min(size.Height / 2, 5 / scale);
            Matrix oldM = g.Transform;
            g.TranslateTransform(startPoint.X, startPoint.Y);
            if(Math.Abs(angle) > float.Epsilon)
                g.RotateTransform((float)angle);

            g.FillRectangle(solidBrush, rectangle);
            g.DrawLine(curPen, size.Width / 2 - crossWidth, size.Height / 2, size.Width / 2 + crossWidth, size.Height / 2);
            g.DrawLine(curPen, size.Width / 2, size.Height / 2 - crossHeight, size.Width / 2, size.Height / 2 + crossHeight);
            g.DrawRectangle(curPen, rectangle);
            if (State == TrackerState.active)//选中
            {

                float cursize = 7 / scale;
                float dx = cursize / 2;
                float x1 = startX - dx;
                float x2 = startX + size.Width / 2 - dx;
                float x3 = startX + size.Width - dx;
                float y1 = startY - dx;
                float y2 = startY + size.Height / 2 - dx;
                float y3 = startY + size.Height - dx;

                g.FillRectangle(BorderBrush, x1, y1, cursize, cursize);   //左上
                g.FillRectangle(BorderBrush, x2, y1, cursize, cursize);  //上
                g.FillRectangle(BorderBrush, x3, y1, cursize, cursize);  //右上

                g.FillRectangle(BorderBrush, x1, y2, cursize, cursize);  //左中
                g.FillRectangle(BorderBrush, x3, y2, cursize, cursize);  //右中

                g.FillRectangle(BorderBrush, x1, y3, cursize, cursize);   //左下
                g.FillRectangle(BorderBrush, x2, y3, cursize, cursize);  //下
                g.FillRectangle(BorderBrush, x3, y3, cursize, cursize);  //右下
            }
            g.Transform = oldM;

            //int startX = -m_size.Width / 2;
            //int startY = -m_size.Height / 2;
            //Rectangle rectangle = new Rectangle(new Point(startX,startY), m_size);
            //int width = Math.Min(m_size.Width / 2, 5);
            //int height = Math.Min(m_size.Height / 2, 5);
            //g.RotateTransform((float)m_angle);
            //g.TranslateTransform(m_center.X, m_center.Y);

            //g.FillRectangle(FillBrush, rectangle);
            //g.DrawLine(BorderPen, -width, 0, +width, 0);
            //g.DrawLine(BorderPen, 0,- height, 0, + height);
            //g.DrawRectangle(BorderPen, rectangle);
            //if(State == TrackerState.selected)//选中
            //{
            //    g.FillRectangle(BorderBrush, startX-2, startY-2,5,5);   //左上
            //    g.FillRectangle(BorderBrush, startX+m_size.Width/2 - 2, startY - 2, 5, 5);  //上
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY - 2, 5, 5);  //右上

            //    g.FillRectangle(BorderBrush, startX - 2, startY + m_size.Height/2 - 2, 5, 5);  //左中
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY + m_size.Height / 2 - 2, 5, 5);  //右中

            //    g.FillRectangle(BorderBrush, startX - 2, startY+m_size.Height - 2, 5, 5);   //左下
            //    g.FillRectangle(BorderBrush, startX + m_size.Width / 2 - 2, startY + m_size.Height - 2, 5, 5);  //下
            //    g.FillRectangle(BorderBrush, startX + m_size.Width - 2, startY + m_size.Height - 2, 5, 5);  //右下

            //}

            //g.ResetTransform();
            //g.RotateTransform(-(float)m_angle);
            //g.TranslateTransform(-ptCenter.X, -ptCenter.Y);
            //g.DrawLine(BorderPen, m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2 - 5, m_start.X + m_size.Width / 2, m_start.Y + m_size.Height / 2 + 5);

            //g.EndContainer();
        }

        public void CopyTo(CDrawRect node)
        {
            base.CopyTo(node);
            node.angle = angle;
            node.startPoint = startPoint;//new PointF(m_start.X, m_start.Y);
            node.size = size;
        }

        /// <summary>
        /// 获取外接矩形
        /// </summary>
        /// <returns></returns>
        public RectangleF GetRect()
        {
            PointF[] points = new PointF[3];
            //points[0] = new PointF(m_start.X,m_start.Y);
            points[0] = new PointF(startPoint.X + size.Width, startPoint.Y);
            points[1] = new PointF(startPoint.X + size.Width, startPoint.Y+ size.Height);
            points[2] = new PointF(startPoint.X, startPoint.Y + size.Height);
            Matrix matrix = new Matrix();
            //matrix.Rotate(m_angle);
            //matrix.Translate(m_start.X,m_start.Y);
            
            matrix.RotateAt(angle, startPoint);//RotateAt(m_angle, PointF((REAL)m_position.left, (REAL)m_position.top), MatrixOrderAppend);
            matrix.TransformPoints(points);
            
            float l = startPoint.X;
            float r = startPoint.X;
            float t = startPoint.Y;
            float b = startPoint.Y;
            for (int i = 0; i < 3; i++)
            {
                if (l > points[i].X)
                    l = points[i].X;
                if (r < points[i].X)
                    r = points[i].X;
                if (t > points[i].Y)
                    t = points[i].Y;
                if (b < points[i].Y)
                    b = points[i].Y;
            }
            RectangleF rect = RectangleF.FromLTRB(l, t, r, b);
            return rect;
        }

        public List<PointF> GetPointFs()
        {
            PointF[] points = new PointF[4];
            points[0] = new PointF(startPoint.X, startPoint.Y);
            points[1] = new PointF(startPoint.X + size.Width, startPoint.Y);
            points[2] = new PointF(startPoint.X + size.Width, startPoint.Y + size.Height);
            points[3] = new PointF(startPoint.X, startPoint.Y + size.Height);
            Matrix matrix = new Matrix();
            //matrix.Rotate(m_angle);
            //matrix.Translate(m_start.X,m_start.Y);

            matrix.RotateAt(angle, startPoint);//RotateAt(m_angle, PointF((REAL)m_position.left, (REAL)m_position.top), MatrixOrderAppend);
            matrix.TransformPoints(points);
            return points.ToList<PointF>();
        }
    
    }
}
